package com.dw.security;

import com.dw.web.dto.Response;
import com.dw.web.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.AuthenticationFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author zhangjing
 * @date 2020/8/21 16:01
 * @Description 需要认证的API被调用前执行的拦截器
 */
public class TokenFilter extends AuthenticationFilter {

    @Override
    protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
        String token = getToken(servletRequest);

        boolean isSuccess = false;
        if (StringUtils.isNotEmpty(token)) {
            isSuccess = this.login(token);

        }
        if (!isSuccess) {
            this.printUnauthorized((HttpServletResponse) servletResponse);
        }
        return isSuccess;
    }

    private boolean login(String token) {
        try {
            Subject subject = SecurityUtils.getSubject();
            //subject.login() 调用 自定义的 TokenRealm 对象，进行认证和授权。
            subject.login(new Token(token));
            return true;
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return false;
        }

    }

    private String getToken(ServletRequest servletRequest) {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        //获取请求头中的Authorization属性
        String authorizationHeader = request.getHeader("access_token");
        if (!StringUtils.isEmpty(authorizationHeader)) {
            return authorizationHeader.replace(" ", "");
        }
        return null;
    }

    private void printUnauthorized(HttpServletResponse response) {
        String content = JsonUtils.toJSONString(Response.unAuthorized());
        response.setContentType("application/json;charset=UTF-8");
        try {
            PrintWriter writer = response.getWriter();
            writer.write(content);
        } catch (IOException var5) {
            var5.printStackTrace();
        }
    }
}
